﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using NChardet;

namespace TestDotnet
{
    class MyCharsetDetectionObserver : NChardet.ICharsetDetectionObserver
    {
        public string Charset = null;

        public void Notify(string charset)
        {
            Charset = charset;
        }
    }

    class Program
    {
        static Encoding getUDE(string filename)
        {
            using (FileStream fs = File.OpenRead(filename)) {
                Ude.CharsetDetector cdet = new Ude.CharsetDetector();
                cdet.Feed(fs);
                cdet.DataEnd();
                return Encoding.GetEncoding(cdet.Charset);
            }
        }

        //static Encoding getChardet(string filename)
        static void getChardet(string filename)
        {
            int lang = 2;//
                         //用指定的语参数实例化Detector
            Detector det = new Detector(lang);
            //初始化
            MyCharsetDetectionObserver cdo = new MyCharsetDetectionObserver();
            det.Init(cdo);

            bool isAscii = true;

            using (var stream = new BinaryReader(new FileStream(filename, FileMode.Open))) {
                byte[] buf = new byte[1024];
                int len;
                bool done = false;

                while ((len = stream.Read(buf, 0, buf.Length)) != 0) {
                    // 探测是否为Ascii编码
                    if (isAscii)
                        isAscii = det.isAscii(buf, len);

                    // 如果不是Ascii编码，并且编码未确定，则继续探测
                    if (!isAscii && !done)
                        done = det.DoIt(buf, len, false);
                }
            }


            //调用DatEnd方法，
            //如果引擎认为已经探测出了正确的编码，
            //则会在此时调用ICharsetDetectionObserver的Notify方法
            det.DataEnd();

            bool found = false;


            if (isAscii) {
                Console.WriteLine("CHARSET = ASCII");
                found = true;
            } else if (cdo.Charset != null) {
                Console.WriteLine("CHARSET = {0}", cdo.Charset);
                found = true;
            }

            if (!found) {
                string[] prob = det.getProbableCharsets();
                for (int i = 0; i < prob.Length; i++) {
                    Console.WriteLine("Probable Charset = " + prob[i]);
                    //return Encoding.GetEncoding(prob[i]);
                }
            }
            //return Encoding.ASCII;
        }

        static Encoding getEncoding(string filename)
        {
            using (var sr = new StreamReader(filename, true)) {
                while (sr.Peek() >= 0) {
                    int c = sr.Read();
                    //Console.WriteLine();
                }
                return sr.CurrentEncoding;
            }
        }

        public static Encoding GetEncoding(string filename)
        {
            // Read the BOM
            var bom = new byte[4];
            using (var file = new FileStream(filename, FileMode.Open, FileAccess.Read)) {
                file.Read(bom, 0, 4);
            }

            // Analyze the BOM
            //if (bom[0] == 0x2b && bom[1] == 0x2f && bom[2] == 0x76) return Encoding.UTF7;
            if (bom[0] == 0xef && bom[1] == 0xbb && bom[2] == 0xbf) return Encoding.UTF8;
            if (bom[0] == 0xff && bom[1] == 0xfe) return Encoding.Unicode; //UTF-16LE
            //if (bom[0] == 0xfe && bom[1] == 0xff) return Encoding.BigEndianUnicode; //UTF-16BE
            //if (bom[0] == 0 && bom[1] == 0 && bom[2] == 0xfe && bom[3] == 0xff) return Encoding.UTF32;
            return Encoding.Default;
        }

        static void readFile(string path)
        {
            //var e = getUDE(path);
            //getChardet(path);
            var e = Encoding.GetEncoding("utf-16le");
            //var e = Encoding.UTF32;

            var s = File.ReadAllText(path, e);

            Console.WriteLine(s);
        }

        static void testDiff()
        {
            List<string> s1 = new List<string>() { "1", "2" };
            List<string> s2 = new List<string>() { "1", "2", "4" };

            var r1 = s1.Except(s2);
            var r2 = s2.Except(s1);

            Console.WriteLine("size:({0}) ({1})", r1.Count(), r2.Count());
        }

        static void Main(string[] args)
        {
            /*
            readFile("D:\\a.txt");
            readFile("D:\\b.txt");
            readFile("D:\\c.txt");
            */
            //readFile("D:\\d.txt");
            testDiff();

            Console.ReadKey();
        }
    }
}
